package com.itheima.em.server.service.impl.tianditu;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.em.config.BaiduServerConfig;
import com.itheima.em.config.EagleConfig;
import com.itheima.em.config.TMapServerConfig;
import com.itheima.em.enums.FenceType;
import com.itheima.em.enums.PointType;
import com.itheima.em.enums.ProviderType;
import com.itheima.em.mapper.PointMapper;
import com.itheima.em.mapper.TraceFenceMapper;
import com.itheima.em.mapper.TraceTerminalMapper;
import com.itheima.em.pojo.Point;
import com.itheima.em.pojo.TraceFence;
import com.itheima.em.pojo.TraceTerminal;
import com.itheima.em.server.config.MybatisPlusConfig;
import com.itheima.em.service.EagleOrdered;
import com.itheima.em.service.FenceService;
import com.itheima.em.service.PointService;
import com.itheima.em.util.SnowflakeIdGenerator;
import com.itheima.em.vo.PageResult;
import com.itheima.em.vo.R;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 天地图标注点实现
 *
 * @author MJJ
 * @version 1.0
 */
@Service("TMapPointService")
@ConditionalOnBean({TMapServerConfig.class, MybatisPlusConfig.class})
public class TMapPointServiceImpl extends ServiceImpl<PointMapper, Point> implements PointService {

    /**
     * 雪花ID生成器
     */
    public  SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(this.getClass().hashCode()%31, this.getProvider().getValue()); // 创建雪花ID生成器，传入机器ID和数据中心ID
    @Resource
    private EagleConfig eagleConfig;
    @Resource
    private TMapWebApiService tMapWebApiService;

    /**
     * 创建标注点
     *
     * @param serverId  服务id
     * @param name      点名称
     * @param desc      描述
     * @param pointType 点类型
     * @param param     参数
     * @return 创建成功，返回点id
     */
    @Override
    public R<Long> createPoint(Long serverId, String name, String desc, PointType pointType, Long groupId, Double lon, Double lat, Map<String, Object> param) {
        //获取到标注点id返回
        Long pointId = idGenerator.generateId();
        //存储围栏数据到数据库
        Point point = new Point();
        point.setProvider(ProviderType.TMAP);
        point.setServerId(serverId);
        point.setGroupId(groupId);
        point.setPointId(pointId);
        point.setName(name);
        point.setDesc(desc);
        point.setType(pointType);
        point.setLongitude(lon);
        point.setLatitude(lat);
        if (param != null) point.setParam(JSONUtil.toJsonStr(param));
        super.save(point);
        return R.success(pointId);
    }

    /**
     * 更新标注点
     *
     * @param serverId  服务id
     * @param pointId   标注点id
     * @param name      围栏名称
     * @param desc      描述
     * @param pointType 点类型
     * @param param     参数
     * @return 创建成功，返回围栏id
     */
    @Override
    public R<String> updatePoint(Long serverId, Long pointId, String name, String desc, PointType pointType, Long groupId, Double lon, Double lat, Map<String, Object> param) {
        //根据点id更新数据
        Point point = new Point();
        point.setGroupId(groupId);
        point.setName(name);
        point.setDesc(desc);
        point.setLongitude(lon);
        point.setLatitude(lat);
        if (param != null)point.setParam(JSONUtil.toJsonStr(param));

        LambdaQueryWrapper<Point> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Point::getPointId, pointId);
        queryWrapper.eq(Point::getProvider, ProviderType.TMAP);
        queryWrapper.eq(Point::getServerId, serverId);
        queryWrapper.eq(Point::getType,pointType);
        super.update(point, queryWrapper);
        return R.success();
    }

    /**
     * 删除标注点
     *
     * @param serverId 服务id
     * @param pointIds 标注点id
     * @return
     */
    @Override
    public R<String> deletePoint(Long serverId, Long... pointIds) {
        if (pointIds.length > 100) {
            return R.error("The number of fences cannot be greater than 100.");
        }
        //删除数据库中的围栏数据
        LambdaQueryWrapper<Point> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Point::getPointId, pointIds);
        queryWrapper.eq(Point::getProvider, ProviderType.TMAP);
        queryWrapper.eq(Point::getServerId, serverId);
        super.remove(queryWrapper);
        return R.success();
    }

    @Override
    public R<PageResult<Point>> queryPointList(Long serverId,PointType pointType,Long groupId,Integer page, Integer pageSize) {
        Page<Point> pointPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<Point> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(pointType != null,Point::getType,pointType);
        queryWrapper.eq(pointType != PointType.DEFAULT && groupId != null,Point::getGroupId,groupId);
        queryWrapper.eq(serverId != null,Point::getServerId,serverId);
        queryWrapper.eq(Point::getProvider, ProviderType.TMAP);
        queryWrapper.orderByDesc(Point::getCreated);
        super.page(pointPage, queryWrapper);
        return R.success(new PageResult<Point>().convert(pointPage));
    }
    /**
     * 根据点id查询标注信息
     *
     * @param serverId 服务id
     * @param pointId  标注点id
     * @return 标注对象数据
     */
    @Override
    public R<Point> queryByPointId(Long serverId, Long pointId) {
        LambdaQueryWrapper<Point> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Point::getProvider, ProviderType.TMAP);
        queryWrapper.eq(Point::getPointId, pointId);
        queryWrapper.eq(serverId != null,Point::getServerId, serverId);
        Point point = super.getOne(queryWrapper);
        if (null != point) {
            return R.success(point);
        }
        return R.error("The data queried does not exist.");
    }

    @Override
    public int getOrder() {
        return EagleOrdered.ONE;
    }

    @Override
    public ProviderType getProvider() {
        return ProviderType.TMAP;
    }


}
